(function(angular) {
	"use strict";
	angular.module("fs.waf").factory("setlDetailEventService", setlDetailEventService);
	setlDetailEventService.$inject = [ "settlementInitFactory", "formatService", "modalService", "arithService", "clsConstants", "payDetailService", "setlDetailService", "fxCrossRateService", "setlDetailStyleService", "setlDetailFxRateService" ];
	function setlDetailEventService(settlementInitFactory, formatService, modalService, arithService, clsConstants, payDetailService, setlDetailService, fxCrossRateService, setlDetailStyleService, setlDetailFxRateService) {
		
		/***********************************************************************
		 * Change the display in the summary item when user change the pay or
		 * receive table allocation code alloc: the selected allocation code"s
		 * value itemNo: the current settlement details index number edited by
		 * Steven Hu on 2006.3.15
		 **********************************************************************/
		function allocCodeChanged(settlement, setlDetail) {
			var alloc = setlDetail.allocCode;
			if (setlDetail.lastAllocCode == alloc) {
				return;
			}
			setlDetail.lastAllocCode = alloc;
			var childFlag = setlDetail.childFlag;
			doAllocCodeChanged(settlement, setlDetail);

			if (childFlag == "N") {
				if (setlDetail) {
					var splitedSetlItemSeq = setlDetail.setlItemSeq;
					angular.forEach(settlement.setlDetails, function(data, index, array) {
						if (data.parentItemSeq == splitedSetlItemSeq) {
							data.allocCode = alloc;
							doAllocCodeChanged(settlement, data, setlDetail);
						}
					});
				}
			}
		}
		
		/***********************************************************************
		 * Function: Use the "C" icon to change the pay amount of items in the
		 * pay or receive table itemType: the item type: P or I or F crdr:
		 * credit or debit: C or D index: index of the current splited record in
		 * settlement details array
		 **********************************************************************/
		function changeAmountBox(settlement, setlDetail) {
			var itemAmtObj = setlDetail.itemAmt;
			var itemCcyVal = setlDetail.itemCcy;
			var isRefund = false;
			var mObj = new Object();
			mObj.itemType = setlDetail.itemType;
			mObj.crDr = setlDetail.crDrFlag;
			mObj.feeId = setlDetail.feeId;
			mObj.feeNewFlag = setlDetail.feeNewFlag;
			mObj.ccy = itemCcyVal;
			mObj.amt = formatService.parseNumber(itemAmtObj);
			mObj.taxRate = settlement.site.taxRate;
			mObj.itemCode = setlDetail.itemCode;
			var limitAmt = formatService.parseNumber(setlDetail.feeAmtOrg);
			// var taxAmt = formatService.parseNumber(setlDetail.taxAmt);
			// limitAmt = arithService.calc(limitAmt, taxAmt,"+");
			if (setlDetail.crDrFlag == "C" && mObj.feeNewFlag == "Y" && mObj.feeId != "")
				isRefund = true;
			if (isRefund) {
				mObj.limtAmt = limitAmt;
			} else
				mObj.limtAmt = limitAmt;
			modalService.openCustomDialogs({
				"title" : "title.changed.amountinfo",
				"dialogsModule" : "cls.settlementInit.changeAmt",
				"size" : [ 500, 300 ],
				"params" : {
					"mObj" : mObj
				},
				"btnCallback" : {
					"ok" : function(retObj) {
						if (typeof retObj != "undefined") {
							callback(retObj, setlDetail);
						}
					}
				}
			});
			function callback(retObj, setlDetail) {
				if (retObj != null) {
					// reset tax amt
					setlDetail.taxAmt = retObj.taxAmt;
					setlDetailStyleService.processTaxWaiveLabel(setlDetail);
					setlDetailStyleService.initSetlDetailStyle(settlement, setlDetail);
					// set itemAmt Before tax
					setlDetail.itemAmtBeforetax = retObj.feeAmt;
					// reset the itemAmt and itemAmtSettled
					setlDetailService.setSetlDetailItemAmtSetled(setlDetail, retObj.returnAmt, "withItemAmt");
					if (settlementInitFactory.getTxnService(settlement.settlementInfo).changeAmountBox) {
						settlementInitFactory.getTxnService(settlement.settlementInfo).changeAmountBox(settlement, setlDetail);
					} else {
						// calculate pay amt
						setlDetail.payAmt = setlDetailService.calculatePayAmt(settlement.site, setlDetail);
						payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
					}

				}
			}
		}
		
		/***********************************************************************
		 * Function: Use the "S" icon to split or merge the items in the pay or
		 * receive table itemType: the item type: P or I or F crdr: credit or
		 * debit: C or D item: index of the current splited record in settlement
		 * details array
		 **********************************************************************/
		function splitbox(settlement, item) {
			var splitSetlDetails = [];
			if (item) {
				var splitedSetlItemSeq = item.setlItemSeq;
				angular.forEach(settlement.setlDetails, function(data, index, array) {
					if (data && data.parentItemSeq == splitedSetlItemSeq) {
						var splitSetlDetail = {};
						splitSetlDetail.payCcy = data.payCcy;
						splitSetlDetail.itemAmtSettled = data.itemAmtSettled;
						splitSetlDetail.setlItemSeq = data.setlItemSeq;
						splitSetlDetails.push(splitSetlDetail);
					}
				});
			}
			var mObj = new Object();
			mObj.itemType = item.itemType;
			mObj.txnCcy = settlement.txnCcy;
			mObj.gccyOptions = settlement.gccyOptions;
			mObj.bccy = settlement.site.baseCcy;
			mObj.parentPayCcyValue = item.payCcy;
			mObj.splitSetlDetails = splitSetlDetails;
			mObj.amtAll = item.itemAmtSettled;
			modalService.openCustomDialogs({
				"title" : "title.popup.split",
				"dialogsModule" : "cls.settlementInit.split",
				"params" : {
					"mObj" : mObj
				},
				"btnCallback" : {
					"ok" : function(retObj) {
						if (typeof retObj != "undefined") {
							retObj.itemType = item.itemType;
							retObj.parentItem = item;
							retObj.splitSetlDetails = splitSetlDetails;
							retObj.crDrFlag = item.crDrFlag;
							retObj.bccy = mObj.bccy;
							split(settlement, retObj);
						}
					}
				}
			});
		}

		function split(settlement, amtObj) {
			var ccy = amtObj.parentItem.itemCcy, alloccode = amtObj.parentItem.allocCode, param = new Object(), i;
			param.itemType = amtObj.itemType;
			param.crdr = amtObj.crDrFlag;
			param.itemCcy = ccy;
			param.itemCode = amtObj.parentItem.itemCode;
			param.itemDesc = amtObj.parentItem.itemDesc;
			param.feeTaxFlag = "N";
			param.taxAmt = "0";
			param.taxWaiveFlag = "N";
			param.allocCode = alloccode;
			param.feeId = "";
			param.itemSubtype = "";
			param.holdFlag = "N";// Y or N
			param.waiveFlag = "N"; // Y or N
			param.carryFlag = "N";// Y or N
			param.transferFlag = "N";// Y or N
			param.uItemWaive = "N";
			param.fxType = amtObj.parentItem.fxRateType;
			param.fxRate = amtObj.parentItem.fxRate;
			param.fxType2 = amtObj.parentItem.fxRateType2;
			param.fxRate2 = amtObj.parentItem.fxRate2;
			param.feeAmtOrg = amtObj.parentItem.feeAmtOrg;
			for (i = 0; i < amtObj.splitSetlDetails.length; i++) {
				var splitSetlDetail = amtObj.splitSetlDetails[i];
				splitSetlDetail.amt = splitSetlDetail.amt || new Number(0);
				splitSetlDetail.itemAmtSettled = splitSetlDetail.itemAmtSettled || new Number(0);
				if (arithService.eq(splitSetlDetail.amt, 0) && arithService.eq(splitSetlDetail.itemAmtSettled, 0)) {
					amtObj.splitSetlDetails.splice(i, 1);
					i--;
				}
			}
			if (amtObj.splitSetlDetails.length == 0) {
				return;
			}
			var parent_itemAmtSettled = arithService.sub(amtObj.parentItem.itemAmtSettled, 0);
			// always reset the mother principal amt
			amtObj.parentItem.itemAmtSettled = arithService.sub(amtObj.amtAll, 0);
			amtObj.parentItem.itemAmt = arithService.sub(amtObj.amtAll, 0);

			var tmpamt = 0;
			var outsAmt = arithService.sub(amtObj.amtAll, 0);
			if (!arithService.eq(outsAmt, parent_itemAmtSettled)) {
				tmpamt = setlDetailService.calculatePayAmt(settlement.site, amtObj.parentItem);
				amtObj.parentItem.payAmt = tmpamt;
				// 20060808 update the payment detail"s amount
				payDetailService.changePaydetailBySetldetail(settlement, amtObj.parentItem);
			}
			for (i = 0; i < amtObj.splitSetlDetails.length; i++) {
				var setlDetail = amtObj.splitSetlDetails[i], setlDetailReal;
				setlDetail.itemAmtSettled = setlDetail.itemAmtSettled || 0;
				setlDetail.amt = setlDetail.amt || 0;
				// delete item
				if (arithService.eq(setlDetail.amt, 0) && arithService.gt(setlDetail.itemAmtSettled, 0)) {
					setlDetailReal = getSetlDetailBySetlItemSeq(settlement.setlDetails, setlDetail.setlItemSeq);
					deleteSetlDetail(settlement, setlDetailReal);
				}
				// 2 change item
				if (arithService.gt(setlDetail.amt, 0) && arithService.gt(setlDetail.itemAmtSettled, 0)) {
					setlDetailReal = getSetlDetailBySetlItemSeq(settlement.setlDetails, setlDetail.setlItemSeq);
					setlDetailReal.itemAmtSettled = setlDetail.amt;
					setlDetailReal.itemAmt = setlDetail.amt;

					if (setlDetailReal.payCcy != setlDetail.ccy) {
						setlDetailReal.payCcy = setlDetail.ccy;
						doChangePayCcy(settlement, setlDetailReal, amtObj.parentItem);
					} else {
						setlDetailReal.payAmt = setlDetailService.calculatePayAmt(settlement.site, setlDetailReal);
						// 20060808 update the payment detail"s amount
						payDetailService.changePaydetailBySetldetail(settlement, setlDetailReal);
					}
				}
				// 3 add item
				if (arithService.gt(setlDetail.amt, 0) && arithService.eq(setlDetail.itemAmtSettled, 0)) {// add
					param.itemAmt = setlDetail.amt;
					param.itemAmtSettled = setlDetail.amt;
					param.payAmt = setlDetail.amt;
					param.payCcy = setlDetail.ccy;
					param.parentItemSeq = amtObj.parentItem.setlItemSeq;
					param.childFlag = "Y";
					param.feeNewFlag = "N";
					param.parentItem = amtObj.parentItem;// only for split
					setlDetailReal = setlDetailService.addSetlDetail(settlement, param, "S");
					// 20060808 add the amount to payment detail
					if (setlDetailReal)
						setlDetailService.setlDetailAddAmt(settlement, setlDetailReal, "B");
					doChangePayCcy(settlement, setlDetailReal, amtObj.parentItem);
				}
			}
		}

		function doChangePayCcy(settlement, setlDetail1, setlDetail2) {
			var itemType = setlDetail1.itemType;
			var childFlag = setlDetail1.childFlag;
			if ((childFlag == "N") || (childFlag == "Y" && itemType == "P")) {
				setlDetailService.resetFxRatesAmdPayAmt(settlement, setlDetail1);
				setlDetailService.updatePaydetailSeqForSetlDetail(settlement, setlDetail1, "payCcyChange");
			} else {
				setlDetailService.initSettlementDetailsChildItem(settlement, setlDetail1, setlDetail2);
			}
			// 20060807 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail1);
			// 2006.9.25 remittance payment
			settlementInitFactory.getFunction(settlement.settlementInfo, "doChangePayCcy")(settlement);
		}

		function getSetlDetailBySetlItemSeq(setlDetails, setlItemSeq) {
			var result = null;
			for (var i = 0; i < setlDetails.length; i++) {
				if (setlItemSeq && setlDetails[i].setlItemSeq == setlItemSeq) {
					result = setlDetails[i];
					break;
				}
			}
			return result;
		}

		/***********************************************************************
		 * update item amount when tax waive checked edited by Steven Hu on
		 * 2006.3.16, updated by Steven Hu on 2016.10.7 to enable
		 * itemAmtBeforetax The rule: itemAmtBeforeTax = feeAmtOrg; itemAmt =
		 * itemAmtBeforeTax + taxAmt; if(waive fee) itemAmtSettled =
		 * itemAmtBeforeTax; if(not waive fee) itemAmtSettled = itemAmtBeforeTax +
		 * taxAmt;
		 **********************************************************************/
		function taxWaiveFlagChanged(settlement, setlDetail) {
			var taxWaiveBox = setlDetail.taxWaiveFlag;
			if (setlDetail.lastTaxWaiveFlag == taxWaiveBox) {
				return;
			}
			setlDetail.lastTaxWaiveFlag = taxWaiveBox;
			var itemAmt = formatService.parseNumber(setlDetail.itemAmtSettled) * 1;
			var taxAmt = formatService.parseNumber(setlDetail.taxAmt) * 1;
			var newItemAmt;
			if (taxWaiveBox == "Y") {
				if (itemAmt >= taxAmt)
					newItemAmt = itemAmt - taxAmt;
				else
					newItemAmt = itemAmt;
				setlDetail.taxAmt_label = "label.settlement.init.taxwaive";
			} else {
				newItemAmt = itemAmt + taxAmt;
				setlDetail.taxAmt_label = "label.settlement.init.tax";
			}
			if (setlDetail.taxAmt && !arithService.eq(setlDetail.taxAmt, 0)) {
				setlDetail.taxAmt_Show = true;
			} else {
				setlDetail.taxAmt_Show = false;
			}
			setlDetail.setlDetailConfig.gridConfigs.taxAmt.label = setlDetail.taxAmt_label;
			setlDetail.itemAmtSettled = newItemAmt;
			setlDetail.itemAmt = newItemAmt;

			// 20070419 recalculate the pay amount after the tax of fee is
			// waived
			var payAmtOld = setlDetail.payAmt;
			var amt = setlDetailService.calculatePayAmt(settlement.site, setlDetail);
			setlDetail.payAmt = amt;
			// 20070419 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);

			settlementInitFactory.getFunction(settlement.settlementInfo, "taxWaiveFlagChanged")(settlement, setlDetail, payAmtOld);
		}

		/***********************************************************************
		 * disable or enable itemWaiveFlag,itemCarryoverFlag and
		 * itemTransferFlag check box; and disable or enable pay method when
		 * user click hold check box itemNo: array index of settlement detail
		 * items
		 **********************************************************************/
		function itemHoldFlagChanged(settlement, setlDetail) {
			if (setlDetail.itemWaiveFlag == "Y" || setlDetail.itemTransferFlag == "Y" || setlDetail.itemCarryoverFlag == "Y") {
				return;
			}
			var holdObj = setlDetail.itemHoldFlag;
			if (setlDetail.lastItemHoldFlag == holdObj) {
				return;
			}
			setlDetail.lastItemHoldFlag = holdObj;
			var isUpdatePayMethod = true;// if decided to update the pay
			// method
			var isDisabled = true;
			if (holdObj == "Y") {
				isUpdatePayMethod = false;
				isDisabled = true;
				setlDetailService.disableSplit(setlDetail, false);
			} else {
				isDisabled = false;
				setlDetailService.disableSplit(setlDetail, true);
			}
			changeItemWaiveFlag(setlDetail, isDisabled);
			changeItemCarryoverFlag(setlDetail, isDisabled);
			changeItemTransferFlag(setlDetail, isDisabled);
			changePaymethod(settlement, setlDetail, isUpdatePayMethod, isDisabled);
			settlementInitFactory.getFunction(settlement.settlementInfo, "itemHoldFlagChanged")(settlement, setlDetail);
		}

		/**
		 * basic util function: disable or enable itemCarryoverFlag
		 * setlDetail:array index of settlement detail items isDisabled: if it
		 * is disabled, true or false
		 */
		function changeItemCarryoverFlag(setlDetail, isDisabled) {
			var carryover = setlDetail.itemCarryoverFlag;
			var uCarryover = setlDetail.uItemCarryover;
			if (carryover) {
				if (uCarryover != "N") {
					setlDetail.itemCarryoverFlag_Readonly = isDisabled;
				}
			}
		}

		/***********************************************************************
		 * disable or enable itemHoldFlag,itemCarryoverFlag and itemTransferFlag
		 * check box; and disable or enable pay method when user click waive
		 * check box itemNo: array index of settlement detail items
		 **********************************************************************/
		function itemWaiveFlagChanged(settlement, setlDetail) {
			if (setlDetail.itemHoldFlag == "Y" || setlDetail.itemTransferFlag == "Y" || setlDetail.itemCarryoverFlag == "Y") {
				return;
			}
			var waive = setlDetail.itemWaiveFlag;
			if (setlDetail.lastItemWaiveFlag == waive) {
				return;
			}
			setlDetail.lastItemWaiveFlag = waive;
			var isUpdatePayMethod = true;// if decided to update the pay
			// method
			var isDisabled = true;
			if (waive == "Y") {
				isDisabled = true;
				isUpdatePayMethod = false;
				setlDetailService.disableSplit(setlDetail, false);
			} else {
				isDisabled = false;
				setlDetailService.disableSplit(setlDetail, true);
			}
			changeTaxWaiveFlag(setlDetail, isDisabled);
			changeItemHoldFlag(settlement, setlDetail, isDisabled);
			changeItemCarryoverFlag(setlDetail, isDisabled);
			changeItemTransferFlag(setlDetail, isDisabled);
			changePaymethod(settlement, setlDetail, isUpdatePayMethod, isDisabled);
			settlementInitFactory.getFunction(settlement.settlementInfo, "itemWaiveFlagChanged")(settlement, setlDetail);
		}
		
		function changeTaxWaiveFlag(setlDetail, isDisabled){
			if(isDisabled){
				setlDetail.taxWaiveFlag = "Y";
			}
			setlDetail.taxWaiveFlag_Readonly = isDisabled;
		}

		/***********************************************************************
		 * disable or enable itemHoldFlag,itemWaiveFlag and itemCarryoverFlag
		 * check box; and change pay method list size, and add a new item
		 * paydetails when user click carryover check box itemNo: array index of
		 * settlement detail items
		 **********************************************************************/
		function itemTransferFlagChanged(settlement, setlDetail) {
			if (setlDetail.itemHoldFlag == "Y" || setlDetail.itemWaiveFlag == "Y" || setlDetail.itemCarryoverFlag == "Y") {
				return;
			}
			var transfer = setlDetail.itemTransferFlag;
			if (setlDetail.lastItemTransferFlag == transfer) {
				return;
			}
			setlDetail.lastItemTransferFlag = transfer;
			if (transfer == "Y") {// when transfer checkbox checked:pay method
				// size == 1
				changeItemHoldFlag(settlement, setlDetail, true);
				changeItemWaiveFlag(setlDetail, true);
				changeItemCarryoverFlag(setlDetail, true);
				// add new pay details
				var payCcy = setlDetail.payCcy;
				var allocCode = setlDetail.allocCode;
				// add a new paydetail and update the settlement detail item"s
				// pay method dropdown list
				// 20060808 don"t put the amount
				// 2007.4.16 updated: when transfer paydetail existed, then use
				// it iterator the payment details
				var isTransferPayDetailExisted = false;// true represents the
				// transfer paydetail existed
				var payMethodValue = 0;
				var payDetails = settlement.payDetails;
				for (var i = 0; i < payDetails; i++) {
					var payDetailCcy = payDetails[i].payCcy;
					var payDetailAlloc = payDetails[i].allocCode;
					if (payDetails[i].itemSubtype == clsConstants.PayDetailItemSubType.TRANSFER_ITEM && payCcy == payDetailCcy && allocCode == payDetailAlloc) {
						var payDetailPayMethod = payDetails[i].payItemSeq;
						var payDetailItemTypeObj = payDetails[i].itemType;
						var setlDetailItemType = setlDetail.itemType;
						isTransferPayDetailExisted = true;
						payMethodValue = payDetailPayMethod;
						if (setlDetail.paydetailSeqType != "text") {// dropdown
							if (setlDetail.paydetailSeqOptions) {
								setlDetail.paydetailSeqOptions.push({
									"value" : payMethodValue,
									"label" : payMethodValue
								});
								setlDetail.paydetailSeq = payMethodValue;
							}
						} else {
							setlDetail.paydetailSeq = payMethodValue;
						}
						if (setlDetailItemType == "P")
							payDetails[i].itemType = "P";
						else if (setlDetailItemType == "I" && payDetailItemTypeObj == "F")
							payDetails[i].itemType = "I";
						break;
					}
				}
				// transfer paydetail didn"t exist
				if (!isTransferPayDetailExisted) {
					payMethodValue = payDetailService.addPayDetailRow(settlement, setlDetail, true, false);
				}
				// addPayDetailRow method only updates the itemSubtype !=
				// ROLLOVER_REMITTANCE settlement detail entry"s payMethod
				if (setlDetail.paydetailSeqType == "text")
					// when itemSubtype == ROLLOVER_REMITTANCE,update the pay
					// method input text
					setlDetail.paydetailSeq = payMethodValue;
				setlDetailService.disableSplit(setlDetail, false);
				// disableAmountIcon(itemNo, "none");
			} else {
				// update the pay method list, or change the pay method input
				// text
				changeItemHoldFlag(settlement, setlDetail, false);
				changeItemWaiveFlag(setlDetail, false);
				changeItemCarryoverFlag(setlDetail, false);
				if (!setlDetailService.isRolloverRemittance(setlDetail.itemSubtype)) {
					// (payDetailSeqFlag == "true")
					setlDetailService.updatePaydetailSeqForSetlDetail(settlement, setlDetail, "change");
				} else {
					updatePayMethodText(setlDetail);
				}
				setlDetailService.disableSplit(setlDetail, true);
			}
			// 20060807 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			// change children
			setlDetailService.changeChildPaymethod(settlement, setlDetail);
		}

		/**
		 * update pay method input text for
		 * itemSubtype=ROLLOVER_REMITTANCE(rollover or remittance) itemNo: array
		 * index of settlement detail item status: load - load page; allocChange -
		 * settlement detail item"s allocation code changed; payCcyChange -
		 * settlement detail item"s pay ccy changed; change - other change
		 * edited by Steven Hu on 2006.6.20
		 */
		function updatePayMethodText(setlDetail) {
			if (setlDetail.rolloverPaydetail) {
				setlDetail.paydetailSeq = setlDetail.rolloverPaydetail;
			}
		}

		function itemCarryoverFlagChanged(settlement, setlDetail) {
			if (setlDetail.itemHoldFlag == "Y" || setlDetail.itemWaiveFlag == "Y" || setlDetail.itemTransferFlag == "Y") {
				return;
			}
			var carryover = setlDetail.itemCarryoverFlag;
			if (setlDetail.lastItemCarryoverFlag == carryover) {
				return;
			}
			setlDetail.lastItemCarryoverFlag = carryover;
			var itemType = setlDetail.itemType;
			var rolloverIntMode = settlement.settlementInfo.rolloverIntMode;
			var rolloverFeeMode = settlement.settlementInfo.rolloverFeeMode;
			var isUpdatePayMethod = true;// if decided to update the pay
			// method
			var isDisabled = true;
			if (carryover == "Y") {
				if (itemType == "I") {
					if (rolloverIntMode == "Y")
						// paymethod is text
						setlDetail.itemSubtype = clsConstants.SetlDetailItemSubType.CARRY_OVER_INTEREST;
					else
						setlDetail.itemSubtype = "";// paymethod is list
				}
				if (itemType == "F") {
					if (rolloverFeeMode == "Y")
						setlDetail.itemSubtype = clsConstants.SetlDetailItemSubType.CARRY_OVER_INTEREST;
					else
						setlDetail.itemSubtype = "";
				}
				if (carryover == "Y") {
					isUpdatePayMethod = false;
					isDisabled = true;
					setlDetailService.disableSplit(setlDetail, false);
				} else {
					isDisabled = false;
					setlDetailService.disableSplit(setlDetail, true);
				}
			}
			changeItemHoldFlag(settlement, setlDetail, isDisabled);
			changeItemWaiveFlag(setlDetail, isDisabled);
			changeItemTransferFlag(setlDetail, isDisabled);
			changePaymethod(settlement, setlDetail, isUpdatePayMethod, isDisabled);
		}

		/**
		 * basic util function: disable or enable itemHoldFlag
		 * setlDetail:array index of settlement detail items
		 * isDisabled: if it is disabled, true or false
		 */
		function changeItemHoldFlag(settlement, setlDetail, isDisabled) {
			var parentType = settlement.settlementInfo.parentType;
			var finalRepayFlag = "";
			if (parentType == "REPAY") {
				finalRepayFlag = settlement.payment.finalRepayFlag;
			}
			if (finalRepayFlag != "Y") {
				setlDetail.itemHoldFlag_Readonly = isDisabled;
			}
		}

		/**
		 * basic util function: disable or enable itemWaiveFlag
		 * setlDetail:array index of settlement detail items
		 * isDisabled: if it is disabled, true or false
		 */
		function changeItemWaiveFlag(setlDetail, isDisabled) {
			var uItemWaiveValue = setlDetail.uItemWaive;
			if (uItemWaiveValue == "Y") {
				setlDetail.itemWaiveFlag_Readonly = isDisabled;
			}
		}

		/**
		 * basic util function: disable or enable itemTransferFlag
		 * setlDetail:array index of settlement detail items
		 * isDisabled: if it is disabled, true or false
		 */
		function changeItemTransferFlag(setlDetail, isDisabled) {
			var transfer = setlDetail.itemTransferFlag;
			var uTransfer = setlDetail.uItemTransfer;
			if (transfer) {
				if (uTransfer != "N") {
					setlDetail.itemTransferFlag_Readonly = isDisabled;
				}
			}
		}

		/**
		 * basic util function: disable or enable its and its children" pay
		 * method, and update the relative amount in payment details only for
		 * hold, waive and carryover functions itemNo:array index of settlement
		 * detail items isUpdatePayMethod: if decided to update the pay method
		 * isDisabled: if payId is disabled, true or false
		 */
		function changePaymethod(settlement, setlDetail, isUpdatePayMethod, isDisabled) {
			// 2006.3.15 now use itemSubtype, future must be decided by U_PAYDETAIL_SEQ flag
			setlDetail.paydetailSeq_Readonly = isDisabled;
			if (!isDisabled) {
				if (!setlDetailService.isRolloverRemittance(setlDetail.itemSubtype)) {
					// (payDetailSeqFlag == "true")
					setlDetailService.updatePaydetailSeqForSetlDetail(settlement, setlDetail, "change");
				} else {
					if (isUpdatePayMethod) {
						updatePayMethodText(setlDetail);
					}
				}
			}
			// 20060807 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			// change children
			setlDetailService.changeChildPaymethod(settlement, setlDetail);
		}

		/**
		 * triggered when checking fxCrossRateFlag radio button
		 * 
		 * @param itemNo
		 */
		function fxCrossRateFlagChanged(settlement, setlDetail) {
			if (setlDetail.lastFxCrossRateFlag == setlDetail.fxCrossRateFlag) {
				return;
			}
			setlDetail.lastFxCrossRateFlag = setlDetail.fxCrossRateFlag;
			fxCrossRateService.FxCrossRate_Util.handleFxCrossRateSpan(setlDetail);
			if (fxCrossRateService.FxCrossRate_Util.isCrossRate(setlDetail)) {
				setlDetailStyleService.disableFxRateAndFxRate2(setlDetail);
			} else {
				setlDetailFxRateService.enableFxRateAndFxRate2(setlDetail, settlement.site.baseCcy);
			}
			// calculate payAmt
			setlDetail.payAmt = setlDetailService.calculatePayAmt(settlement.site, setlDetail);
			// 20070419 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			settlementInitFactory.getFunction(settlement.settlementInfo, "fxCrossRateFlagChanged")(settlement, setlDetail);
			payCcyChanged(settlement, setlDetail);
			setlDetailStyleService.fxCrossStyle(setlDetail);
		}

		function payCcyChanged(settlement, item, data) {
			doChangePayCcy(settlement, item, data);
			if (item.childFlag == "N") {
				var itemType = item.itemType;
				if (itemType != "P") {
					angular.forEach(settlement.setlDetails, function(data, index, array) {
						if (data.parentItemSeq == item.setlItemSeq) {
							data.payCcy = item.payCcy;
							doChangePayCcy(settlement, data, item);
						}
					});
				}
			}
		}

		/***********************************************************************
		 * Caculate the pay amount based on the fx1 & fx2 rates fx: which
		 * exchange rate type: the assigned exchange rate"s type itemNo: array
		 * index of settlement detail item 2006.3.14 modified by Steven Hu
		 **********************************************************************/
		function changefxRateType(settlement, setlDetail, fx) {
			var type = "";
			if (fx == "fxr1") {
				type = setlDetail.fxRateType;
			} else {
				type = setlDetail.fxRateType2;
			}
			var fxRate = 0;
			var bccy = settlement.site.baseCcy;
			var itemccy = setlDetail.itemCcy;
			var payccy = setlDetail.payCcy;

			var fromCcy = "";
			if (fx == "fxr1") {
				fromCcy = payccy;
			}
			if (fx == "fxr2") {
				fromCcy = itemccy;
			}
			// if(type == "C") {
			// curFxRate;
			// }
			fxRate = getIndexofFxRateArr(settlement, bccy, fromCcy);
			var rate, fxRate_Readonly;
			switch (type) {
			case "B":
				rate = fxRate.buyRate;
				fxRate_Readonly = true;
				break;
			case "S":
				rate = fxRate.sellRate;
				fxRate_Readonly = true;
				break;
			case "K":
				rate = fxRate.bookRate;
				fxRate_Readonly = true;
				break;
			case "C":
				rate = fxRate.customRate;
				fxRate_Readonly = false;
				break;
			case "P":// spot rate
				rate = fxRate.bookRate;
				fxRate_Readonly = false;
				break;
			default:
				rate = "";
				fxRate_Readonly = true;
				break;
			}
			if (fx == "fxr1") {
				setlDetail.fxRate = rate;
				setlDetail.fxRate_Readonly = fxRate_Readonly;
			} else if (fx == "fxr2") {
				setlDetail.fxRate2 = rate;
				setlDetail.fxRate2_Readonly = fxRate_Readonly;
			}
			doChangefxRateType(settlement, setlDetail);
		}
		
		function doChangefxRateType(settlement, setlDetail){
			var oldPayAmt = setlDetail.payAmt;
			var amt = setlDetailService.calculatePayAmt(settlement.site, setlDetail);
			setlDetail.payAmt = amt;
			//20060807 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			settlementInitFactory.getFunction(settlement.settlementInfo, "doChangefxRateType")(settlement, setlDetail, oldPayAmt);
			//set its childs payAmt and fxRate		
			var itemTypeVal = setlDetail.itemType;
			var childFlag = setlDetail.childFlag;
			if((childFlag == "N") && (itemTypeVal != "P"))	{
				if(setlDetail){
					var splitedSetlItemSeq = setlDetail.setlItemSeq;
					angular.forEach(settlement.setlDetails, function(data, index, array){
						if(data && (data.parentItemSeq == splitedSetlItemSeq)){
							setlDetailService.setChildAmtAndRateByParent(data, setlDetail, settlement.site);
						}
					});
				}
			}
		}

		/***********************************************************************
		 * get the index of fxRateArry which the fromCcy to base ccy is params:
		 * fromCcy: transcation currency Notes: 2006.3.23 added by Steven Hu
		 **********************************************************************/
		function getIndexofFxRateArr(settlement, bccy, fromCcy) {
			var fxRate = {}, i, data;
			for(i = 0; i < settlement.fxRates.length; i++){
				data = settlement.fxRates[i];
				if (fromCcy != bccy && data.ccyFrom == fromCcy && data.ccyTo == bccy) {
					fxRate = data;
				}
			}
			return fxRate;
		}

		function fxCrossRateChanged(settlement, setlDetail) {
			var oldPayAmt = setlDetail.payAmt;
			setlDetail.payAmt = setlDetailService.calculatePayAmt(settlement.site, setlDetail);
			// 20060807 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			// 20060818 add pay priority
			settlementInitFactory.getFunction(settlement.settlementInfo, "fxCrossRateChanged")(settlement, setlDetail, oldPayAmt);
			// set its childs payAmt and fxRate
			if ((setlDetail.childFlag == "N") && (setlDetail.itemType != "P")) {
				if (setlDetail) {
					var splitedSetlItemSeq = setlDetail.setlItemSeq;
					angular.forEach(settlement.setlDetails, function(data, index, array) {
						if (data && (data.parentItemSeq == splitedSetlItemSeq)) {
							setlDetailService.setChildAmtAndRateByParent(data, setlDetail, settlement.site);
						}
					});
				}
			}
		}

		/***********************************************************************
		 * delete item in the pay or receive table in settlement details array
		 * table: table id prefix: its format: dr<%=sdIndex%> edited by Steven
		 * Hu on 2006.3.16
		 **********************************************************************/
		function deleteSetlDetail(settlement, setlDetail) {
			// 20060808 delete the settlement pay id object
			if (setlDetail) {
				setlDetailService.setlDetailDeleteAmt(settlement, setlDetail, "B");
			}
			var isDelete = doDeleteSetlDetail(settlement, setlDetail);
			settlementInitFactory.getFunction(settlement.settlementInfo, "splitToDeleteSetlDetail")(settlement, setlDetail);
			return isDelete;
		}

		/***********************************************************************
		 * delete item in the pay or receive table in settlement details array.
		 * This is private method, it"s called by deleteSetlDetail method only.
		 * table: table id prefix: its format: dr<%=sdIndex%> edited by Steven
		 * Hu on 2007.4.12
		 **********************************************************************/
		function doDeleteSetlDetail(settlement, setlDetail) {
			var success = false;
			for (var i = 0; i < settlement.setlDetails.length; i++) {
				var data = settlement.setlDetails[i];
				if (data.setlItemSeq == setlDetail.setlItemSeq) {
					settlement.setlDetails.splice(i, 1);
					success = true;
					break;
				}
			}
			return success;
		}

		function doAllocCodeChanged(settlement, setlDetail, parentSetlDetail){
			if(settlementInitFactory.getTxnService(settlement.settlementInfo).doAllocCodeChanged) {
				settlementInitFactory.getTxnService(settlement.settlementInfo).doAllocCodeChanged(settlement, setlDetail, parentSetlDetail);
			} else {
				var itemType = setlDetail.itemType;
				var childFlag = setlDetail.childFlag;
				if((childFlag == "N") || (childFlag == "Y" && itemType == "P")){
					setlDetailService.updatePaydetailSeqForSetlDetail(settlement, setlDetail, "allocChange");
				}else{
					if(parentSetlDetail)
						setlDetailService.initSettlementDetailsChildItem(settlement, setlDetail, parentSetlDetail);
				}
				//20060807 update the payment detail relative amount
				payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			}
		}

		function feebox(target, settlement) {
			var feeObj = setlDetailService.getFeeObjParam(settlement);
			if (target == "addcr") {
				feeObj.crDrFlag = "C";
				modalService.openCustomDialogs({
					"title" : "title.popup.addfee",
					"dialogsModule" : "cls.settlement.addFeeForPay",
					"size" : [ 800, 300 ],
					"params" : {
						"feeObj" : feeObj
					},
					"btnCallback" : {
						"ok" : function(param) {
							setlDetailService.feeboxCallback(settlement, param, target);
						}
					}
				});
			} else if (target == "adddr") {
				feeObj.crDrFlag = "D";
				modalService.openCustomDialogs({
					"title" : "title.popup.addfee",
					"dialogsModule" : "cls.settlement.addFeeForReceive",
					"size" : [ 800, 300 ],
					"params" : {
						"feeObj" : feeObj
					},
					"btnCallback" : {
						"ok" : function(param) {
							setlDetailService.feeboxCallback(settlement, param, target);
						}
					}
				});
			}
		}
		
		/************************************
		change pay method in settlement detail item
		itemNo:
		    array index of settlement detail item
		************************************/
		function paydetailSeqChanged(settlement, setlDetail){
			//20060807 update the payment detail relative amount
			payDetailService.changePaydetailBySetldetail(settlement, setlDetail);
			//20060816 add to the pay priority list
			//2006.9.25 remittance payment
			settlementInitFactory.getFunction(settlement.settlementInfo, "paydetailSeqChanged")(settlement, setlDetail);
		}
		
		function getFxCrossRate(settlement, setlDetail){
//			var contractNo = setlDetail.fxContractNo;
//			var payCcy = setlDetail.payCcy;
//			var payAmt = setlDetail.payAmt;
		}
		

		return {
			allocCodeChanged : allocCodeChanged,
			changeAmountBox : changeAmountBox,
			changefxRateType : changefxRateType,
			deleteSetlDetail : deleteSetlDetail,
			feebox : feebox,
			fxCrossRateChanged : fxCrossRateChanged,
			fxCrossRateFlagChanged : fxCrossRateFlagChanged,
			getFxCrossRate : getFxCrossRate,
			itemCarryoverFlagChanged : itemCarryoverFlagChanged,
			itemHoldFlagChanged : itemHoldFlagChanged,
			itemTransferFlagChanged : itemTransferFlagChanged,
			itemWaiveFlagChanged : itemWaiveFlagChanged,
			payCcyChanged : payCcyChanged,
			paydetailSeqChanged : paydetailSeqChanged,
			splitbox : splitbox,
			taxWaiveFlagChanged : taxWaiveFlagChanged
		};
	}
})(angular);
